package br.mil.eb.pqrmnt7.scc.persistence.jpa.ordemabastecimento;

import java.util.Date;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import br.mil.eb.pqrmnt7.scc.entity.Motorista;
import br.mil.eb.pqrmnt7.scc.entity.OrdemAbastecimento;
import br.mil.eb.pqrmnt7.scc.entity.OrdemAbastecimentoEntity;
import br.mil.eb.pqrmnt7.scc.entity.SituacaoOrdemDeAbastecimento;
import br.mil.eb.pqrmnt7.scc.entity.TipoCombustivel;
import br.mil.eb.pqrmnt7.scc.entity.Viatura;
import br.mil.eb.pqrmnt7.scc.persistence.jpa.AppJpaDAO;

import com.powerlogic.jcompany.commons.PlcBaseContextVO;
import com.powerlogic.jcompany.commons.PlcException;
import com.powerlogic.jcompany.commons.annotation.PlcAggregationDAOIoC;
import com.powerlogic.jcompany.commons.config.stereotypes.SPlcDataAccessObject;
import com.powerlogic.jcompany.persistence.jpa.PlcQuery;
import com.powerlogic.jcompany.persistence.jpa.PlcQueryFirstLine;
import com.powerlogic.jcompany.persistence.jpa.PlcQueryLineAmount;
import com.powerlogic.jcompany.persistence.jpa.PlcQueryOrderBy;
import com.powerlogic.jcompany.persistence.jpa.PlcQueryParameter;
import com.powerlogic.jcompany.persistence.jpa.PlcQueryService;
/**
 * Classe de Persistência gerada pelo assistente
 */

@PlcAggregationDAOIoC(OrdemAbastecimentoEntity.class)
@SPlcDataAccessObject
@PlcQueryService
public class OrdemAbastecimentoDAO extends AppJpaDAO  {

	private static final Log logger = LogFactory.getLog(OrdemAbastecimentoDAO.class);	
	
	@Inject
	PlcBaseContextVO context;
	
	@PlcQuery("querySel")
	public native List<OrdemAbastecimentoEntity> findList(
			PlcBaseContextVO context,
			@PlcQueryOrderBy String dynamicOrderByPlc,
			@PlcQueryFirstLine Integer primeiraLinhaPlc, 
			@PlcQueryLineAmount Integer numeroLinhasPlc,		   
			
			@PlcQueryParameter(name="numero", expression="obj.numero = :numero") Long numero,
			@PlcQueryParameter(name="dataExpedicao", expression="obj.dataExpedicao = :dataExpedicao") Date dataExpedicao,
			@PlcQueryParameter(name="viatura", expression="obj1 = :viatura") Viatura viatura,
			@PlcQueryParameter(name="motorista", expression="obj2 = :motorista") Motorista motorista,
			@PlcQueryParameter(name="situacao", expression="obj.situacao = :situacao") SituacaoOrdemDeAbastecimento situacao,
			@PlcQueryParameter(name="dataAbastecimento", expression="obj.dataAbastecimento = :dataAbastecimento") Date dataAbastecimento
	);

	@PlcQuery("querySel")
	public native Long findCount(
			PlcBaseContextVO context,
			@PlcQueryParameter(name="numero", expression="obj.numero = :numero") Long numero,
			@PlcQueryParameter(name="dataExpedicao", expression="obj.dataExpedicao = :dataExpedicao") Date dataExpedicao,
			@PlcQueryParameter(name="viatura", expression="obj1 = :viatura") Viatura viatura,
			@PlcQueryParameter(name="motorista", expression="obj2 = :motorista") Motorista motorista,
			@PlcQueryParameter(name="situacao", expression="obj.situacao = :situacao") SituacaoOrdemDeAbastecimento situacao,
			@PlcQueryParameter(name="dataAbastecimento", expression="obj.dataAbastecimento = :dataAbastecimento") Date dataAbastecimento
	);
	
	public Long calculaSaldo(TipoCombustivel tipoCombustivel){
		
		try {
			
			logger.debug("Chegou ao calcula saldo no OrdemAbastecimentoDAO");
			
			EntityManager entityManager = getEntityManager(context);
			
			Query query = entityManager.createNamedQuery("OrdemAbastecimentoEntity.calculaSaldo");
			query.setParameter("tipoCombustivel",tipoCombustivel);
			
			logger.debug("query retornada: " + query);
			
			Long saldoPorTipoDeCombustivel = (Long) query.getSingleResult();
			
			logger.debug("saldoPorTipoDeCombustivel: " + saldoPorTipoDeCombustivel);
			
			return saldoPorTipoDeCombustivel;
			
		} catch (Exception e) {
			throw new PlcException("OrdemAbastecimentoDAO","calculaSaldo",e,log,"");
		}
		
	} 

	@SuppressWarnings("unchecked")
	public List<OrdemAbastecimento> recuperaComMesInformado(Date anoMesReferencia){
		
		try {
			
			logger.debug("Chegou ao recupera no OrdemAbastecimentoDAO");
			
			EntityManager entityManager = getEntityManager(context);
			
			logger.debug("anoMesReferencia: " + anoMesReferencia);
			
			List resultList = entityManager.createNamedQuery("OrdemAbastecimentoEntity.recuperaTodasConfirmadas")
									       .getResultList();
			
			logger.debug("Número de entidades recuperadas: " + resultList.size());
			
			return resultList;
			
		} catch (Exception e) {
			logger.error(e);
			throw new PlcException("OrdemAbastecimentoDAO","recuperaComTipoEMesInformados",e,log,"");
		}
		
	} 

	@SuppressWarnings("unchecked")
	public List<OrdemAbastecimento> recuperaComTipoEMesInformados(TipoCombustivel tipoCombustivel, Date anoMesReferencia){
		
		try {
			
			logger.debug("Chegou ao recupera no OrdemAbastecimentoDAO");
			
			EntityManager entityManager = getEntityManager(context);
			
			return entityManager.createNamedQuery("OrdemAbastecimentoEntity.recuperaComTipoEMesInformados")
									   .setParameter("tipoCombustivel",tipoCombustivel.getNome())
									   .setParameter("anoMesReferencia",anoMesReferencia)
									   .getResultList();
			
		} catch (Exception e) {
			logger.error(e);
			throw new PlcException("OrdemAbastecimentoDAO","recuperaComTipoEMesInformados",e,log,"");
		}
		
	}

	public List<OrdemAbastecimento> recuperaTodasConfirmadasPorPeriodo(Date dataInicio,
			Date dataFim) {
		try {
			
			logger.debug("Chegou ao recupera no OrdemAbastecimentoDAO");
			
			EntityManager entityManager = getEntityManager(context);
			
			logger.debug("dataInicio: " + dataInicio);
			logger.debug("dataFim: " + dataFim);
			
			List resultList = entityManager.createNamedQuery("OrdemAbastecimentoEntity.recuperaTodasConfirmadasPorPeriodo")
										   .setParameter("dataInicio",dataInicio)
										   .setParameter("dataFim",dataFim)
									       .getResultList();
			
			logger.debug("Número de entidades recuperadas: " + resultList.size());
			
			return resultList;
			
		} catch (Exception e) {
			logger.error(e);
			throw new PlcException("OrdemAbastecimentoDAO","recuperaTodasConfirmadasPorPeriodo",e,log,"");
		}
	}	

	public List<OrdemAbastecimento> recuperaPorPeriodo(Date dataInicio, Date dataFim) {
		try {
			
			logger.debug("Chegou ao recupera no OrdemAbastecimentoDAO");
			
			EntityManager entityManager = getEntityManager(context);
			
			logger.debug("dataInicio: " + dataInicio);
			logger.debug("dataFim: " + dataFim);
			
			List resultList = entityManager.createNamedQuery("OrdemAbastecimentoEntity.recuperaPorPeriodo")
										   .setParameter("dataInicio",dataInicio)
										   .setParameter("dataFim",dataFim)
									       .getResultList();
			
			logger.debug("Número de entidades recuperadas: " + resultList.size());
			
			return resultList;
			
		} catch (Exception e) {
			logger.error(e);
			throw new PlcException("OrdemAbastecimentoDAO","recuperaPorPeriodo",e,log,"");
		}
	}

	public Long count() {
		try {
			
			logger.debug("Chegou ao proximoNumeroDeOrdem no OrdemAbastecimentoDAO");
			
			EntityManager entityManager = getEntityManager(context);
			
//			int resultList = entityManager.createNamedQuery("OrdemAbastecimentoEntity.proximoNumeroDeOrdem").getFirstResult();
			
			List resultList = entityManager.createNamedQuery("OrdemAbastecimentoEntity.querySel")
				       .getResultList();
			
			logger.debug("proximoNumeroDeOrdem: " + resultList.size());
			
			return new Long(resultList.size());
			
		} catch (Exception e) {
			logger.error(e);
			throw new PlcException("OrdemAbastecimentoDAO","proximoNumeroDeOrdem",e,log,"");
		}

	}	
	
}
